package org.abratuhi.kvngroupware.pubsub;

import java.util.Date;

public class Subscription{
	
	public String subscriptionId;
	public String subscriberId;
	public String[] attributes;
	public Value[] minimums;
	public Value[] maximums;
	
	public Subscription(String subscriptorId, String[] attributes, Value[] mins, Value[] maxs){
		this.subscriberId = subscriptorId;
		this.subscriptionId = subscriptorId + new Date().getTime();
		this.attributes = attributes;
		this.minimums = mins;
		this.maximums = maxs;
	}
	
	public int indexOf(String attribute){
		for(int i=0; i<attributes.length; i++){
			if(attributes[i].equals(attribute)){
				return i;
			}
		}
		return -1;
	}
	
	public Value minOf(String attribute){
		return (indexOf(attribute) != 1)? minimums[indexOf(attribute)] : null;
	}
	
	public Value maxOf(String attribute){
		return (indexOf(attribute) != 1)? maximums[indexOf(attribute)] : null;
	}
	
	public boolean within(String attribute, Value min, Value max){
		return (min.compareTo(minOf(attribute))<0 && max.compareTo(maxOf(attribute))>0);
	}
	
	public boolean outL(String attribute, Value min, Value max){
		return (!intersects(attribute, min, max) && maxOf(attribute).compareTo(min)<0);
	}
	
	public boolean outR(String attribute, Value min, Value max){
		return (!intersects(attribute, min, max) && minOf(attribute).compareTo(max)>0);
	}
	
	public boolean extL(String attribute, Value min, Value max){
		return (intersects(attribute, min, max) && minOf(attribute).compareTo(min)<0);
	}
	
	public boolean extR(String attribute, Value min, Value max){
		return (intersects(attribute, min, max) && maxOf(attribute).compareTo(max)>0);
	}
	
	public boolean intersects(String attribute, Value min, Value max){
		return (intersects1(attribute, min, max)/* ||
				intersects2(attribute, min, max)*/);
	}
	
	public boolean intersects1(String attribute, Value min, Value max){
		Value thismin = minOf(attribute);
		Value thismax = maxOf(attribute);
		Value thatmin = min;
		Value thatmax = max;
		return (thismax.compareTo(thatmin) >= 0 && thismin.compareTo(thatmax) <= 0);
	}
	
	public boolean intersects2(String attribute, Value min, Value max){
		Value thismin = minOf(attribute);
		Value thismax = maxOf(attribute);
		Value thatmin = min;
		Value thatmax = max;
		return !((thatmax.equals("*") && thismin.compareTo(thatmin) < 0 && thismax.compareTo(thatmin) < 0) ||
				(thatmin.equals("*") && thismin.compareTo(thatmax) > 0 && thismax.compareTo(thatmax) > 0));
	}
	
	public boolean matches(Publication pub, String attribute){
		Value value = pub.valueOf(attribute);
		Value min = minOf(attribute);
		Value max = maxOf(attribute);
		if(value != null && !value.equals("*") && min != null && max != null){
			if(min.compareTo(value) <= 0 && value.compareTo(max) <= 0){
				return true;
			}
		}
		else if(value != null && value.equals("*") && min != null && max != null){
			return true;
		}
		return false;
	}
	
	public boolean matches(Publication pub){
		for(int i=0; i<pub.attributes.length; i++){
			if(!matches(pub, pub.attributes[i])){
				return false;
			}
		}
		return true;
	}
	
	public String toString(){
		String result = subscriptionId + ": "+subscriberId+"; ";
		for(int i=0; i<attributes.length; i++){
			result += minimums[i].toString() + " <= " + attributes[i] + " <= " + maximums[i].toString() + ", ";
		}
		result += ";";
		return result;
	}

}
